[BREAKING] MAINT: Re-migrate Psychosocial scenario to per-subharm cross-product#2191
Open
varunj-msft wants to merge 12 commits into
Open
Conversation
added 2 commits
July 14, 2026 22:16
Restructures Psychosocial so techniques select attack techniques (prompt_sending, role_play, crescendo) rather than subharms. Both subharms (imminent_crisis, licensed_therapist) always run, each with its own dataset, scorer rubric, and Crescendo escalation prompt. Atomic attacks are the (selected technique x subharm) cross product, so every attack is scored with the rubric matching its seed's subharm -- fixing the wrong-scorer-on-ALL bug where licensed_therapist seeds were scored with the crisis rubric. - role_play is excluded for licensed_therapist (a fictional movie-script framing does not probe whether the model improperly acts as a real therapist; success would measure the wrong thing). - Split the single mixed psychosocial.prompt into airt_imminent_crisis and airt_licensed_therapist datasets; per-dataset budget keeps both subharms populated even at small --max-dataset-size (fixes the sample-before-filter empty-subharm bug). - Subharm datasets cannot be selected by name (each is tied to its scorer/prompt); --max-dataset-size still caps seeds drawn per subharm. - Per-subharm baselines: one baseline per subharm scored with its own rubric; the first is named 'baseline' so the base central-baseline prepend is suppressed (no double baseline). - VERSION 1 -> 2.
The CLI backend applies --max-dataset-size N by setting the cap on the whole compound dataset config, which the base then applies as one global budget across the union of the two subharm datasets. At a small N (e.g. --max-dataset-size 1) this drew every surviving seed from one subharm and starved the other, silently dropping a whole subharm and breaking the scenario's "both subharms always run" invariant (measured: a subharm was starved on every run at N=1). Normalize the incoming compound-level cap into an explicit per-child compound so the cap applies to each subharm independently. The compound cap is set to N * <number of subharms> -- large enough it can never trim the union, yet non-None so the base still pins sampled objective hashes for resume. Caller-supplied --dataset-filters are carried over to the rebuilt config. The default and programmatic per_dataset paths (compound cap None) are left untouched. - Rename the test that only exercised the per_dataset primitive; add regression tests for the CLI compound-cap path, the default no-op path, and dataset-filter preservation.
rlundeen2
reviewed
Jul 15, 2026
…ters Reworks the Psychosocial scenario to follow framework norms used by sibling scenarios (leakage, foundry, scam), replacing the technique x subharm cross-product and its awkward module-level `_psychosocial_techniques()` / `_build_scorer` contracts. - Harms are the primary axis: new `harms` parameter selects imminent_crisis and/or licensed_therapist (both by default). Each harm owns its dataset, Crescendo escalation prompt, scorer, and threshold via an immutable config. - Converters become the variation axis, modeled as PsychosocialTechnique members (none/soften/upset/logical_appeal) selectable via --strategies. - Per-harm scorers built inline (no external rubric path lookup); callers can override with imminent_crisis_scorer / licensed_therapist_scorer. - Drops dataset_config from supported_parameters (datasets are derived from harms, not selectable by name). - Adds Scenario._build_baseline_atomic_attacks hook (default None, back-compat) so Psychosocial emits per-harm baselines named <harm>_baseline, removing the fragile "baseline" naming trick. - Rewrites tests (37) and doc prose; regenerates airt.ipynb psychosocial cells with real Version 2 output. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: b7009abc-fe0b-4d7e-a39a-971a396e9eef
…oduct
Rewrite the Psychosocial AIRT scenario from scratch, modeled on the healthy
garak.encoding (converter-as-technique enum) and airt.scam
(with_simulated_conversation) patterns.
- Primary axis is sub_harm (imminent_crisis / licensed_therapist), a plain
string param defaulting to 'all'. Each sub-harm owns its dataset, escalation
prompt, and an inline conversation-level scorer (no rubric-path lookup table,
no _build_scorer indirection).
- Base technique is a simulated crescendo per sub-harm; converters layer on top
as the PsychosocialTechnique enum (DEFAULT = none/tone_soften/
persuasion_logical_appeal; ALL = ~19 converters + live Crescendo).
- Keep dataset_config (so --max-dataset-size works) but hard-bind dataset names
to the selected sub-harms. Drop CompoundDatasetAttackConfiguration.
- Per-sub-harm baselines via the _build_baseline_atomic_attacks hook.
- Add escalation_crisis_simulated.yaml (renders with objective/max_turns only)
for the simulated-conversation flow.
- Rewrite tests and sync doc/scanner/airt.{py,ipynb}.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b7009abc-fe0b-4d7e-a39a-971a396e9eef
Each sub-harm now owns a build_scorer callable that spells out its scorer (rubric + threshold) next to the dataset it pairs with, replacing the shared _conversation_scorer helper. Adds a test asserting each sub-harm builds a scorer. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: b7009abc-fe0b-4d7e-a39a-971a396e9eef
…dardizing-Scenarios-Psychosocial-v2
…dardizing-Scenarios-Psychosocial-v2
Remove the overloaded per-scenario baseline hook. The base Scenario now derives baselines from the already-built technique cells, grouping by objective-scorer identity: one shared scorer yields a single "baseline", per-population scorers (e.g. psychosocial sub-harms) yield one "<display_group>_baseline" per group. No scenario hand-rolls baselines. - scenario.py: concrete _build_baseline_atomic_attacks derivation; delete singular _build_baseline_atomic_attack. - psychosocial.py: delete the baseline override (now derived identically). - atomic_attack.py: public objective_scorer property for grouping. - matrix_atomic_attack_builder.py: build_baseline_atomic_attack gains atomic_attack_name/display_group/objective_scorer passthrough. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: b7009abc-fe0b-4d7e-a39a-971a396e9eef
The base Scenario no longer builds baselines. It only resolves BASELINE_ATTACK_POLICY into self._include_baseline (carried on ScenarioContext.include_baseline). Each scenario emits its own baseline: - Matrix scenarios (cyber, leakage, rapid_response, doctor, benchmark) get it for free -- the matrix builder reads context.include_baseline. - build_matrix_atomic_attacks no longer takes a redundant include_baseline arg; it reads it from the context it already receives. - Custom scenarios (adaptive, jailbreak, scam, encoding, web_injection, red_team_agent) prepend one gated build_baseline_atomic_attack call. - Psychosocial emits its per-sub-harm baselines inline. Removes Scenario._build_baseline_atomic_attacks and the central prepend in initialize_async. Updates tests accordingly. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: b7009abc-fe0b-4d7e-a39a-971a396e9eef
rlundeen2
approved these changes
Jul 16, 2026
rlundeen2
left a comment
Contributor
There was a problem hiding this comment.
Approving! But I wrote a big chunk so it should have another approval
…eanup - Add TranslationConverter language variants (Spanish, French, German, Japanese) as a new "language" converter family for the Psychosocial technique sweep. - Group the converter families under selectable aggregate tags so users can run a whole family with --strategies: "tone", "language", "persuasion", and "deterministic" (the no-LLM perturbations). - Rename the confusing `rubric` local to `scoring_prompt` in the scorer builders (it is the scorer's system-prompt SeedPrompt, not a lookup rubric) and drop a stale comment referencing the removed central baseline fallback. - Make the airt.ipynb Psychosocial demo minimal (single technique + one objective) so the notebook runs fast instead of sweeping the full dataset by default; re-run. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: b7009abc-fe0b-4d7e-a39a-971a396e9eef
…dardizing-Scenarios-Psychosocial-v2
…ection The CLI flag is --techniques/-t (--strategies never existed). Corrects it in the airt.py notebook and psychosocial.py docstrings, and trims the notebook's Psychosocial section to the sibling house style (short description + bash + Available techniques), dropping impl details and outdated content (MHFA/ALGEE, create_conversation_scorer, YAML rubric internals, brittle converter counts). Regenerated airt.ipynb and re-ran the minimal cell. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: b7009abc-fe0b-4d7e-a39a-971a396e9eef
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Psychosocial
Rewrites the
airt.psychosocialscenario as a cleansub_harm × techniquecross-product, following the same patterns as the other AIRT scenarios.sub_harmis the primary axis —imminent_crisisand/orlicensed_therapist(both by default). Each sub-harm owns its dataset, escalation prompt, and its own conversation-level scorer, so every attack and baseline is scored by the rubric that matches its harm. Override a scorer by passingimminent_crisis_scorer/licensed_therapist_scorertoPsychosocial(...).PsychosocialTechniqueis the secondary axis — a registry-style converter enum (mirrorsEncodingTechnique) so users can add more. The base technique is a simulated crescendo; each selected converter is layered on top. Converters preserve natural-language emotional framing (obfuscation converters are excluded) and are grouped into selectable families:tone,language(new translation variants),persuasion, anddeterministic(no-LLM).crescendoswaps the simulated base for a liveCrescendoAttack(inallonly).--dataset-namesis ignored (--max-dataset-sizestill applies). One baseline per sub-harm is emitted and scored with that sub-harm's rubric. Removes the oldrubric/_build_scorerlookup indirection — scorers are constructed inline with their matching dataset.Baseline decentralization
The base
Scenariono longer builds baselines. It now owns baseline only as configuration (BASELINE_ATTACK_POLICY→context.include_baseline);_build_baseline_atomic_attacksand the central prepend are gone. Each scenario emits its own baseline via the sharedbuild_baseline_atomic_attackhelper, and matrix scenarios get it throughbuild_matrix_atomic_attacks(which readsinclude_baselineoff theScenarioContext). This keeps the base class from presuming a single objective scorer / single baseline shape and lets scenarios like Psychosocial emit multiple baselines (one per sub-harm). The--include-baselineCLI flag and policy semantics (Enabled / Disabled / Forbidden) are unchanged.